﻿#pragma once

#include "DirectShow/dshowcapture.hpp"
#include <memory>

namespace Device
{
	enum class ImageType
	{
		Unknown = 0,
		YUYV422 = 1,
		YUV422 = 2,
		YUV420 = 3
	};

	struct VideoBuffer
	{
		int width;
		int height;
		ImageType type;
		std::shared_ptr<unsigned char> buffer;
		long long startTime;
		long long stopTime;
		long long frameInterval;
	};
}

typedef std::function<void()> VideoCallBack;
typedef std::function<void(const DShow::AudioConfig& config, unsigned char* data,
	size_t size, long long startTime, long long stopTime)> AudioCallBack;

class InputDevice
{
public:
	InputDevice();
	~InputDevice();

	/** 初始化, 并选择摄像头设备与分辨率 */
	void setup(DShow::VideoDevice* videoDevice, DShow::VideoInfo* videoInfo, DShow::AudioDevice* audioDevice);

	/** 设置视频回调 */
	void setVideoCallBack(VideoCallBack& callBack);

	/** 设置音频回调 */
	void setAudioCallBack(AudioCallBack& callBack);

	/** 开始 */
	void start();

	/** 关闭 */
	void stop();

	/** 获取缓存的数据 */
	std::shared_ptr<Device::VideoBuffer>& buffer();

	/** 枚举摄像头 */
	static bool EnumVideoDevices(std::vector<DShow::VideoDevice>& devices);

	/** 枚举麦克风 */
	static bool EnumAudioDevices(std::vector<DShow::AudioDevice>& devices);

private:
	DShow::Device* _device;
	VideoCallBack _videoCallBack;
	AudioCallBack _audioCallBack;

	/** 数据缓存 */
	bool _index;
	std::shared_ptr<Device::VideoBuffer> _buffer[2];

	/** 摄像头数据回调 */
	void onVideoBuffer(const DShow::VideoConfig& config, unsigned char* data,
		size_t size, long long startTime, long long stopTime, long rotationt);

	/** 麦克风数据回调 */
	void onAudioBuffer(const DShow::AudioConfig& config, unsigned char* data,
		size_t size, long long startTime, long long stopTime);

	/** 日志回调 */
	static void onLog(DShow::LogType type, const wchar_t* msg, void* param);
};